Share
Embed
Transcript
39 slides
-
ࣗݾհ • @ota42y • αʔόαΠυΤϯδχΞ • RubyͷਓͰ͕͢ࠓ΄΅PythonͷΈ • Amazon Web
ServicesαʔόʔϨεϨγϐͬͯຊΛॻ͖·ͨ͠ (AWS Serverless Application Modelʹ͍ͭͯͷ) -
RubyͷձࣾͳͷͰϞσϧͷӡ༻͕͍͠ • FiNCͷαʔό΄ͱΜͲ͕Ruby on Rails • ৯ࣄͷࣸਅΛอଘ͢ΔαʔόRuby on RailsͰͰ͖͍ͯΔ •
ͦͷ··ͰTensorFlowͷϞσϧ͑ͳ͍ -
ӡ༻ΘΓͱେม… • ϞσϧΛӡ༻͢ΔαʔόΛॻ͔ͳ͍͍ͯ͘ͷศར • ΞϓϦαʔόΛ࡞Δ͜ͱʹूதͰ͖Δ • GPUαʔόͷཧɺεέʔϧࣗͨͪͰΔඞཁ͕͋Δ • ϞσϧϑΝΠϧͷߋ৽ϑϩʔߏங •
DockerԽͯ͠ΔͱΑΓ͘͜͠… • gRPCͱALBͷ૬ੑ͕ѱͯ͘… -
TensorFlowͷϞσϧΛಈ͔͢ • (࣮࣭)ϑϧϚωʔδυͳTensorFlow Serving͕͑Δ • ϞσϧΛ༻ҙ͢ΕΦʔτεέʔϧ͢ΔREST API͕ੜ͑Δ • S3ʹϞσϧϑΝΠϧΛஔ͍࣮࣭ͯ3ߦॻ͚ͩ͘ from
sagemaker.tensorflow.serving import Model model = Model(model_data='s3://xxx/model.tar.gz', role=……) model.deploy(initial_instance_count=1, instance_type=‘ml.c5.xlarge') -
Ruby͔ΒݺͿ • AWSͷSDKʹJSONͰσʔλΛ͚ͩ͢ client = Aws::SageMakerRuntime::Client.new(access_key_id: ....) res = client.invoke_endpoint({
endpoint_name: "endpoint", body: data.to_json, content_type: ...}) -
Before After S3 ECS্ͷ Ruby on Rails ECS্ͷ TensorFlow Serving
ࣸਅΛS3͔Βऔಘ ࣸਅΛผͤ͞Δ (gPRC) S3 ECS্ͷ Ruby on Rails SageMaker ࣸਅΛS3͔Βऔಘ ࣸਅΛผͤ͞Δ (JSON) -
• ݩʑECS্ͷTensorFlow ServingʹgRPCͰૹͬͯͨ • ըૉͷྻJSONʹ͢Δͱ༰ྔ͕ΕΔ • (n*n) pxͷRGB͔ΒͳΔྻΛJSONʹ͢Δͱ2ʙ3ഒʹ ؒͷεϖʔεແ͠([1,2] rubyͱ͔)
ؒͷεϖʔε͋Γ([1, 2] pythonͱ͔) • ࠓ·Ͱͳ͔͚ͬͨͲJSONͩͱ…ʘ(^o^)ʗ Կ͕ʹͳ͔ͬͨ 8n2 + 2n + 1 3n2 11n2 + 2n 3n2 -
• TensorFlow Serving͕ड͚Δͷσʔλͷྻ • શ෦ࠐΈͰͷΞϓϦͳͷͰҙͷॲཧΛೖΕΒΕΔ෦ແ͍ • ͱ͍͏͔ެࣜυΩϡϝϯτʹॻ͍ͯ͋Δ • ଧͭखͳ͔͠…ʘ(^o^)ʗ TensorFlow
Servingతʹແཧͦ͏ 5FOTPS'MPX4FSWJOHCBTFETFSWFSUPQSPWJEFBTVQFSTFUPGUIF5FOTPS'MPX4FSWJOH 3&45"1*5IJTPQUJPOEPFTOPUSFRVJSF PSBMMPX BDVTUPNQZUIPOTDSJQU -
SageMaker্ͰલॲཧΛ࣮ߦͰ͖Δ • σϓϩΠ࣌ʹ࣮ߦ͢ΔϑΝΠϧΛؚΊΔ͚ͩ (class͕ҧ͏ͷͰҙ) • requirements.txtͰґଘύοέʔδೖΕΒΕΔ from sagemaker.tensorflow import TensorFlowModel
model = TensorFlowModel(model_data = 's3://xxx/model.tar.gz', ɹɹɹɹɹɹɹɹɹɹɹɹɹɹ entry_point='pred.py', role=...) model.deploy(initial_instance_count=1, instance_type='ml.c5.xlarge') -
entry_point.pyͷྫ import numpy as np def input_fn(serialized_input, content_type): """An input_fn
that loads a pickled object""" if request_content_type == "application/python-pickle": deserialized_input = pickle.loads(serialized_input) return deserialized_input else: # Handle other content-types here or raise an Exception # if the content type is not supported. pass def output_fn(prediction_result, accepts): """An output_fn that dumps a pickled object as response""" if request_content_type == "application/python-pickle": return np.dumps(prediction_result) else: # Handle other content-types here or raise an Exception # if the content type is not supported. pass -
εΫϦϓτ͜Μͳײ͡ import boto3 import json import numpy as np from
PIL import Image import io AWS_S3_BUCKET_NAME = 'NAME' s3 = boto3.resource('s3') def input_fn(serialized_input, content_type): request_json = json.loads(serialized_input.decode()) s3_key = request_json['key'] response = s3.Object(AWS_S3_BUCKET_NAME, s3_key).get() image_bytes = response['Body'].read() img = Image.open(io.BytesIO(image_bytes)) bmp_data = np.asarray(img) return bmp_data[np.newaxis, :, :] ೖྗJSONͰ {“key”: “/path/to/a.jpg”} S3͔Βը૾ΛऔΓ RGBʹม ͜͜ʹ༰ྔ੍ݶͳ͍ -
Before After S3 ECS্ͷ Ruby on Rails SageMaker ࣸਅΛผͤ͞Δ (JSON)
S3 ECS্ͷ Ruby on Rails SageMaker ࣸਅΛS3͔Βऔಘ S3ͷkey͚ͩૹΔ (༰ྔখ) ࣸਅΛS3͔Βऔಘ ͕ͩͬͨ͜͜ -
Before After S3 ECS্ͷ Ruby on Rails SageMaker ࣸਅΛผͤ͞Δ (JSON)
S3 ECS্ͷ Ruby on Rails SageMaker ࣸਅΛS3͔Βऔಘ S3ͷkey͚ͩૹΔ (༰ྔখ) ࣸਅΛS3͔Βऔಘ ௨৴ྔ͕ݮͬͯϨεϙϯεૣ͘ -
TensorFlow, the TensorFlow logo and any related marks are trademarks
of Google Inc. TensorFlow Logo Copyright © 2019 The TensorFlow authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.